/**
 * This file is part of Idegen, the application to create IDE project files.
 *
 * @copyright Copyright (c) 2011-2012, Walter Tamboer http://waltertamboer.nl
 * @file Idegen/Application/CommandLineParser.cpp
 */

#include "Idegen/PrecompiledHeader.hpp"
#include "Idegen/Application/CommandLineParser.hpp"

namespace Idegen
{
	CommandLineParser::CommandLineParser()
	{
	}

	CommandLineParser::~CommandLineParser()
	{
	}

	bool CommandLineParser::Parse( int argc, char* argv[] )
	{
		for ( int i = 0; i < argc; ++i )
		{
			// The value of the argument:
			std::string argument = argv[ i ];

			// Walk through all the falgs to see if there is a match:
			for ( FlagList::iterator it = m_Flags.begin(); it != m_Flags.end(); ++it )
			{
				Flag& flag = (*it);

				// Is the argument equal to this flag?
				if ( flag.Name == argument || flag.ShortName == argument )
				{
					// There must be a next argument:
					if ( i < argc )
					{
						flag.HasValueBeenSet = true;
						flag.Value = argv[ ++i ];
					}
				}
			}
		}

		// Parsing succeeded when all the values have been set of the flags that really need to be set.
		bool result = true;

		for ( FlagList::iterator it = m_Flags.begin(); it != m_Flags.end(); ++it )
		{
			const Flag& flag = (*it);

			if ( flag.Required )
			{
				result &= flag.HasValueBeenSet;
			}
		}

		return result;
	}

	void CommandLineParser::AddFlag( const std::string& name, const std::string& description, bool required )
	{
		Flag flag;

		flag.Required = required;
		flag.HasValueBeenSet = false;
		flag.Name = name;
		flag.Description = description;

		AddFlag( flag );
	}

	void CommandLineParser::AddFlag( const std::string& name, const std::string& shortName, const std::string& description, bool required )
	{
		Flag flag;

		flag.Required = required;
		flag.HasValueBeenSet = false;
		flag.Name = name;
		flag.ShortName = shortName;
		flag.Description = description;

		AddFlag( flag );
	}

	void CommandLineParser::AddFlag( const Flag& flag )
	{
		for ( FlagList::iterator it = m_Flags.begin(); it != m_Flags.end(); ++it )
		{
			Flag& tempFlag = (*it);
			if ( tempFlag.Name == flag.Name )
			{
				// The flag already exists, update it with this information:
				tempFlag.ShortName = flag.ShortName;
				tempFlag.Description = flag.Description;
				return;
			}
		}
		
		// Add the new flag:
		m_Flags.push_back( flag );
	}

	bool CommandLineParser::HasFlag( const std::string& name ) const
	{
		bool result = false;

		for ( FlagList::const_iterator it = m_Flags.begin(); it != m_Flags.end(); ++it )
		{
			const Flag& flag = (*it);

			if ( flag.Name == name || flag.ShortName == name )
			{
				result = flag.HasValueBeenSet;
				break;
			}
		}

		return result;
	}

	std::string CommandLineParser::GetFlagValue( const std::string& name ) const
	{
		std::string flagValue;

		for ( FlagList::const_iterator it = m_Flags.begin(); it != m_Flags.end(); ++it )
		{
			const Flag& flag = (*it);

			if ( flag.Name == name || flag.ShortName == name )
			{
				flagValue = flag.Value;
				break;
			}
		}

		return flagValue;
	}
}
